<?php

namespace App\Console\Commands;

use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class Swoole extends Command
{
    public $ws;
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'swoole {action?}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'swoole';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $action = $this->argument('action');
        switch ($action) {
            case 'close':
                break;
            default:
                $this->start();
                break;
        }

    }

    public function start()
    {
        //创建websocket服务器对象，监听0.0.0.0:9502端口
        $this->ws = new \swoole_websocket_server("0.0.0.0", 2346);

        $this->ws->set(
            array(
                'worker_num' => 1,
//                'daemonize' => 1,
                'max_request' => 100,
                'dispatch_mode' => 2,
                'debug_mode' => 1,
                'heartbeat_idle_time' => 300, //
                'heartbeat_check_interval' => 300,  // 表示每90秒遍历一次
            )
        );
        //监听WebSocket连接打开事件
        $this->ws->on('open', function ($ws, $request) {
            dump($request->fd . "已经连接成功了！！！！！");

        });

        //监听WebSocket消息事件
        $this->ws->on('message', function ($ws, $frame) {
            echo "Message: {$frame->data}\n";
//            $ws->push($frame->fd, "server: {$frame->data}");
            $time = Carbon::now()->toDateTimeString();
//            $ws->push($frame->fd, "{$time}: {$frame->fd}say:{$frame->data}");

            foreach ($ws->connections as $fd) {
                dump($fd);
                $ws->push($fd, $time . ':用户' . $frame->fd . '说:' . $frame->data);
            }
//            var_dump($ws->connection_info($frame->fd));
            //fd绑定客户端传过来的标识uid
//            Log::info("推送消息-message-fd:" . $frame->fd . ":data:" . json_encode($frame->data));
//            $ws->bind($frame->fd, $frame->data);
//            echo "fb：" . $frame->fd . ";uid:" . $frame->data;


//            $user_id = $frame->data;
//            Redis::set("swoole_notice_" . $frame->fd, $user_id);
//            $exist = $this->existNotice($user_id);
//            echo "存在输入：";
//            var_dump(Redis::get("swoole_notice_" . $frame->fd));
//            echo "存在输入中间：";
//            var_dump($exist);
//            echo "存在输入结束：";
//            if ($exist) {
//                $this->ws->push($frame->fd, 200);
//            } else {
//                $this->ws->push($frame->fd, 203);
//            }


        });

        $this->ws->on('request', function ($request, $response) {
            Log::info("推送消息-request:" . json_encode($request->post));
            // 接收http请求从post获取参数
            // 获取所有连接的客户端，验证uid给指定用户推送消息
            // token验证推送来源，避免恶意访问
            if ($request->post['token'] == "tianbao") {
                foreach ($this->ws->connections as $fd) {
                    echo "总连接的fd：" . $fd;
                    if ($this->ws->isEstablished($fd)) {

                        if (!empty(Redis::get("swoole_notice_" . $fd))) {
                            $user_id = Redis::get("swoole_notice_" . $fd);
                            echo "子连接的fd：" . $fd . ";user_id:" . $user_id;
                            $exist = $this->existNotice($user_id);
                            if ($exist) {
                                $this->ws->push($fd, 200);

                            } else {
                                $this->ws->push($fd, 204);
                            }

                        } else {
                            $this->ws->push($fd, 205);
                        }


                    }
                }


            }
        });

        //监听WebSocket连接关闭事件
        $this->ws->on('close', function ($ws, $fd) {
//            Redis::del("swoole_notice_" . $fd);
            echo "client:{$fd} is closed\n";
        });

        $this->ws->on('WorkerStart', function ($server, $worker_id) {
            echo "worker start worker_id {$worker_id}\n";

//            if (0 === $worker_id) {
//                $server->tick(30000, function () use ($server) {
//
//                    echo "tick start \n";
//
//                    foreach ($server->connections as $fd) {
//                        if ($server->isEstablished($fd)) {
//                            $server->push($fd, true, 9);
//                        }
//                    }
//                });
//            }

        });

        $this->ws->start();


    }

    public function existNotice($user_id)
    {
        return (new EarlyWarningNotice())->noticeExist($user_id);
    }
}
